package com.easyaop.commons;

import org.objectweb.asm.Type;

/**
 * @author lipan
 * @since 2025-04-07
 */
public enum Wrapper {
    DEFAULT(Type.getType(Object.class), Type.getType(Object.class), "Object", "Object"),

    VOID(Type.getType(Void.class), Type.VOID_TYPE, "Void", "void"),

    BOOLEAN(Type.getType(Boolean.class), Type.BOOLEAN_TYPE, "Boolean", "boolean"),

    BYTE(Type.getType(Byte.class), Type.BYTE_TYPE, "Byte", "byte"),

    SHORT(Type.getType(Short.class), Type.SHORT_TYPE, "Short", "short"),

    CHAR(Type.getType(Character.class), Type.CHAR_TYPE, "Character", "char"),

    INT(Type.getType(Integer.class), Type.INT_TYPE, "Integer", "int"),

    LONG(Type.getType(Long.class), Type.LONG_TYPE, "Long", "long"),

    FLOAT(Type.getType(Float.class), Type.FLOAT_TYPE, "Float", "float"),

    DOUBLE(Type.getType(Double.class), Type.DOUBLE_TYPE, "Double", "double");

    private final Type wrapperType;

    private final Type primitiveType;

    private final String wrapperSimpleName;

    private final String primitiveSimpleName;

    private static final Wrapper[] FROM_PRIM;

    private static final Wrapper[] FROM_WRAP;

    Wrapper(Type wrapperType, Type primitiveType, String wrapperSimpleName, String primitiveSimpleName) {
        this.wrapperType = wrapperType;
        this.primitiveType = primitiveType;
        this.wrapperSimpleName = wrapperSimpleName;
        this.primitiveSimpleName = primitiveSimpleName;
    }

    public Type primitiveType() {
        return this.primitiveType;
    }

    public Type wrapperType() {
        return this.wrapperType;
    }

    public String wrapperSimpleName() {
        return wrapperSimpleName;
    }

    public String primitiveSimpleName() {
        return primitiveSimpleName;
    }

    public static Wrapper forPrimitiveType(Type primitiveType) {
        Wrapper var1 = findPrimitiveType(primitiveType);
        if (var1 != null) {
            return var1;
        }
        throw new IllegalArgumentException("not primitive: " + primitiveType);
    }

    public static Wrapper findPrimitiveType(Type primitiveType) {
        Wrapper var1 = FROM_PRIM[hashPrim(primitiveType)];
        return var1 != null && var1.primitiveType.equals(primitiveType) ? var1 : null;
    }

    public static Wrapper forWrapperType(Type wrapperType) {
        Wrapper var1 = findWrapperType(wrapperType);
        if (var1 != null) {
            return var1;
        }
        throw new IllegalArgumentException("not wrapper: " + wrapperType);
    }

    public static Wrapper findWrapperType(Type wrapperType) {
        Wrapper var1 = FROM_WRAP[hashWrap(wrapperType)];
        return var1 != null && var1.wrapperType.equals(wrapperType) ? var1 : null;
    }

    public static boolean isPrimitiveType(Type type) {
        switch (type.getSort()) {
            case Type.VOID:
            case Type.BOOLEAN:
            case Type.CHAR:
            case Type.BYTE:
            case Type.SHORT:
            case Type.INT:
            case Type.FLOAT:
            case Type.LONG:
            case Type.DOUBLE:
                return true;
            default:
                return false;
        }
    }

    private static int hashPrim(Type primitiveType) {
        int sort = primitiveType.getSort();
        return sort % 16;
    }

    private static int hashWrap(Type wrapperType) {
        String var1 = wrapperType.getClassName();

        return var1.length() < 13 ? 0 : (3 * var1.charAt(11) + var1.charAt(12)) % 16;
    }

    static {
        FROM_PRIM = new Wrapper[16];
        FROM_WRAP = new Wrapper[16];
        Wrapper[] var0 = values();
        for (Wrapper var3 : var0) {
            int var4 = hashPrim(var3.primitiveType);
            int var5 = hashWrap(var3.wrapperType);

            assert FROM_PRIM[var4] == null;

            assert FROM_WRAP[var5] == null;

            FROM_PRIM[var4] = var3;
            FROM_WRAP[var5] = var3;
        }
    }
}
